using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class UIMsgDispatcher : IUIGlobalEventController
    {
        #region 对象池
        public uint MaxStore => 50;

        public void OnReset()
        {
            this.Clear();
        }

        public void Put2Pool()
        {
            ClassPool.PutAutoType(this);
        }

        static public IUIGlobalEventController NewFromPool()
        {
            return ClassPool.Get<UIMsgDispatcher>();
        }
        #endregion

        private readonly Dictionary<MsgEventType, Delegate> bindEvent = new(4);

        public void AddListener(MsgEventType eventType, MsgDispatcher.Callback callback)
        {
            MsgDispatcher.AddListener(eventType, callback);
            this.bindEvent.TryAdd(eventType, null);
            this.bindEvent[eventType] = Delegate.Combine(this.bindEvent[eventType], callback);
        }

        public void AddListener<T>(MsgEventType eventType, MsgDispatcher.Callback<T> callback)
        {
            MsgDispatcher.AddListener(eventType, callback);
            this.bindEvent.TryAdd(eventType, null);
            this.bindEvent[eventType] = Delegate.Combine(this.bindEvent[eventType], callback);
        }

        public void AddListener<T1, T2>(MsgEventType eventType, MsgDispatcher.Callback<T1, T2> callback)
        {
            MsgDispatcher.AddListener(eventType, callback);
            this.bindEvent.TryAdd(eventType, null);
            this.bindEvent[eventType] = Delegate.Combine(this.bindEvent[eventType], callback);
        }

        public void AddListener<T1, T2, T3>(MsgEventType eventType, MsgDispatcher.Callback<T1, T2, T3> callback)
        {
            MsgDispatcher.AddListener(eventType, callback);
            this.bindEvent.TryAdd(eventType, null);
            this.bindEvent[eventType] = Delegate.Combine(this.bindEvent[eventType], callback);
        }

        public void AddListener<T1, T2, T3, T4>(MsgEventType eventType, MsgDispatcher.Callback<T1, T2, T3, T4> callback)
        {
            MsgDispatcher.AddListener(eventType, callback);
            this.bindEvent.TryAdd(eventType, null);
            this.bindEvent[eventType] = Delegate.Combine(this.bindEvent[eventType], callback);
        }

        private void RemoveListener()
        {
            foreach (var rPair in this.bindEvent)
            {
                MsgDispatcher.RemoveDelegate((int)rPair.Key, rPair.Value);
            }
            this.bindEvent.Clear();
        }

        public void Clear()
        {
            this.RemoveListener();
        }
    }
}
